#ifndef RES_DECL_H_
#define RES_DECL_H_

typedef unsigned int ctl_err_code;

#define DECL_RES(type) \
  typedef struct { \
    ctl_err_code ec; \
    type value; \
  } ctl_res_##type;

#define DECL_RES_P(type) \
  typedef struct { \
    ctl_err_code ec; \
    type* value; \
  } ctl_res_##type##_p;

#define DECL_RES_PP(type) \
  typedef struct { \
    ctl_err_code ec; \
    type** value; \
  } ctl_res_##type##_pp;

#define CHECK_COND_RET_RES(cond, __ec, res) \
  if (!(cond)) { \
    (res).ec = (__ec); \
    backtrace() ;\
    printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #cond); \
    return (res); \
  }
  
#define CHECK_COND_POSTRROC_RET_RES(cond, __ec, res, __POSTPROC) \
  if (!(cond)) { \
    (res).ec = (__ec); \
    printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #cond); \
    __POSTPROC; \
    return (res); \
  }

#define CHECK_COND_RET_EC(cond, __ec) \
  if (!(cond)) { \
    printf("%s %s %u: %s\n", __FILE__, __FUNCTION__, __LINE__, #cond); \
    return (__ec); \
  }

#define CHECK_COND_POSEPROC_RET_EC(cond, __ec, __POSTPROC) \
  if (!(cond)) { \
    printf("%s %s %u: %s %s\n", __FILE__, __FUNCTION__, __LINE__, #cond); \
    __POSTPROC; \
    return (__ec); \
  }

#define CHECK_EXEC_EC_RET_EC(__EXPR, __ec) \
  (__ec) = (__EXPR); \
  if (EOK != (__ec)) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      return (__ec); \
  }

#define CHECK_EXEC_EC_POSTPROC_RET_EC(__EXPR, __ec, __POSTPROC) \
  (__ec) = (__EXPR); \
  if (EOK != (__ec)) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      __POSTPROC; \
      return (__ec); \
  }


#define CHECK_EXEC_EC_RET_RES(__EXPR, __ec, res) \
  (__ec) = (__EXPR); \
  if (EOK != (__ec)) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      (res).ec = __ec; \
      return (res); \
  }

#define CHECK_EXEC_EC_POSTPROC_RET_RES(__EXPR, __ec, res, __POSTPROC) \
  (__ec) = (__EXPR); \
  if (EOK != (__ec)) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      (res).ec = ec; \
      __POSTPROC; \
      return (res); \
  }

#define CHECK_EXEC_RES_RET_RES(__EXPR, res1, res2) \
  (res1) = (__EXPR); \
  if (EOK != (res1).ec) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      (res2).ec = (res2).ec; \
      return (res2); \
  }

#define CHECK_EXEC_RES_POSTPROC_RET_RES(__EXPR, res1, res2, __POSTPROC) \
  (res1) = (__EXPR); \
  if (EOK != (res1).ec) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      (res2).ec = (res1).ec; \
      __POSTPROC; \
      return (res2); \
  }

#define CHECK_EXEC_RES_RET_RC(__EXPR, res, __ec) \
  (res) = (__EXPR); \
  if (EOK != (res).ec) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      return (res).ec; \
  }

#define CHECK_EXEC_RES_POSTPROC_RET_RC(__EXPR, res, __ec, __POSTPROC) \
  (res) = (__EXPR); \
  if (EOK != (res).ec) { \
      printf("%s %s %u : %s\n", __FILE__, __FUNCTION__, __LINE__, #__EXPR); \
      __POSTPROC; \
      return (res).ec; \
  }


#endif